$title Minimal

* ------------------------------------------------------------------------------
* Simplified CGE model in %-change like ORANI-G, but with only 7 sectors,
* a simplified treatment of taxes, and no margins or multiproduction.
* Laurent Cretegny, CoPS, Monash University, Australia, 2004.
* ------------------------------------------------------------------------------

sets
  user              all users
  ind(user)         industries and commodities
  src               source of commodities
  fac               primary factors;

alias (user,u), (ind,i), (i,o), (fac,f);

parameters
  factor(f,i)       wages and profits
  use(o,src,u)      use matrix
  v1ptx(i)          production tax revenue
  v0mtx(o)          import tax revenue
  sigma(o)          Armington elasticities
  sigma1prim(i)     primary factor substitution elasticity
  exp_elast(o)      export demand elasticities;

$gdxin minimal
$load user ind src fac factor use v1ptx v0mtx sigma sigma1prim exp_elast
$gdxin

parameters
  usedom(o,u)       domestic use matrix
  useimp(o,u)       import use matrix
  interm(o,u)       aggregated use matrix
  va(i)             value-added
  labour(i)         labour
  capital(i)        capital
  output(i)         domestic production
  invest            investment
  expend            household expenditure 
  govexp            government expenditure
  export(o)         exports
  import(o)         imports (net of tariff)
  bty(i)            production tax rate
  btm(o)            import tariff rate
  bpy(i)            production price
  bpm(o)            import price
  bpw               world price
  bbop              balance of payments (surplus)
  bc                consumption
  brw               real wage;

usedom(o,u) = use(o,'dom',u);
useimp(o,u) = use(o,'imp',u);
interm(o,u)$(not sameas(u,"exp")) = sum(src, use(o,src,u));

va(i) = sum(f, factor(f,i));
labour(i) = factor("lab",i);
capital(i) = factor("cap",i);

output(i) = sum(o, interm(o,i)) + va(i) + v1ptx(i);
bty(i) = v1ptx(i) / output(i);
bpy(i) = 1 - bty(i);

invest = sum(o, interm(o,'inv'));
expend = sum(o, interm(o,'hh'));
govexp = sum(o, interm(o,'gov'));

export(o) = use(o,'dom','exp');
import(o) = sum(u, use(o,'imp',u)) - v0mtx(o);
btm(o)$import(o) = v0mtx(o) / import(o);
bpw(o) = 1;
bpm(o) = bpw(o) * (1 + btm(o));
bbop = sum(o, export(o) - import(o));

bc = 1;
brw = 1;

$ontext
$model:minimal

$sectors:
  y(i)                        ! production
  a(o,u)$interm(o,u)          ! Armington index
  v(i)                        ! value-added
  m(o)                        ! import index
  c                           ! household consumption
  j                           ! aggregate investment
  g                           ! government demand

$commodities:
  pd(i)                       ! domestic price of output
  pa(o,u)$interm(o,u)         ! Armington price index
  pv(i)                       ! price index for value-added
  pl                          ! price of labour (wage rate)
  pk(i)                       ! price of capital (sector specific)
  pm(o)                       ! price of imports
  pfx                         ! real exchange rate
  pc                          ! consumer price index
  pj                          ! price of a unit of investment
  pg                          ! price of a unit of government output

$consumers:
  ra                ! representative agent

$auxiliary:
  e(o)              ! export index
  efx               ! total exports in foreign exchange
  bop               ! balance of payments index (surplus)
  upl               ! unemployment index

$prod:y(i)          s:0.0                         ! Excerpt 6, 9 : E_p1tot, E_pA
  o:pd(i)           q:output(i)         p:bpy(i)  a:ra      t:bty(i)
  i:pa(o,i)         q:interm(o,i)    
  i:pv(i)           q:va(i)

$prod:a(o,u)$interm(o,u)        s:sigma(o)        ! Excerpt 4 : E_p_s
  o:pa(o,u)         q:interm(o,u)
  i:pd(o)           q:usedom(o,u)
  i:pm(o)           q:useimp(o,u)

$prod:v(i)          s:sigma1prim(i)               ! Excerpt 5 : E_p1prim
  o:pv(i)           q:va(i)
  i:pl              q:labour(i)
  i:pk(i)           q:capital(i)

$prod:m(o)                                        ! Excerpt 10 : E_pB
  o:pm(o)           q:(import(o)*bpm(o))
  i:pfx             q:import(o)         p:bpm(o)  a:ra      t:btm(o)

$prod:c             s:1.0                         ! Excerpt 7 : E_p3tot
  o:pc              q:expend
  i:pa(o,"hh")      q:interm(o,"hh")

$prod:j
  o:pj              q:invest
  i:pa(o,"inv")     q:interm(o,"inv")

$prod:g
  o:pg              q:govexp
  i:pa(o,"gov")     q:interm(o,"gov")

$demand:ra
  d:pc
  e:pl              q:(sum(i, labour(i)))
  e:pk(i)           q:capital(i)
  e:pj              q:-invest                     ! Closure : aggregate investment fixed
  e:pg              q:-govexp                     ! Closure : government demand fixed
  e:pfx             q:1                           r:efx
  e:pd(o)           q:-export(o)                  r:e(o)
  e:pfx             q:-bbop                       r:bop
  e:pl              q:(-sum(i, labour(i)))        r:upl

$constraint:e(o)                                  ! Excerpt 8 : E_x4a
  e(o) =e= (pd(o) / (pfx*bpw(o)))**(-exp_elast(o));

$constraint:efx
  efx =e= sum(o, e(o)*export(o));

$constraint:bop                                   ! Closure : balance of payments free
  c =e= bc;                                       ! Closure : consumption fixed

$constraint:upl                                   ! Closure : level of employment free
  pl =e= brw * pc;                                ! Closure : real wage fixed

$report:
  v:cons(o)         i:pa(o,"hh")        prod:c

$offtext
$sysinclude mpsgeset minimal

* Initialize levels on auxiliary variables

upl.lo = -inf;
bop.lo = -inf;

upl.l = 0;
bop.l = 1;

e.l(o) = 1;
efx.l = sum(o, export(o));

* Fixation of the exchange rate as the numeraire

pfx.fx = 1;

* Benchmark replication

minimal.iterlim = 0;
$include minimal.gen
solve minimal using mcp;
abort$(abs(minimal.objval) gt 1e-4) '*** minimal does not calibrate ! ***';
minimal.iterlim = 10000;

* Counterfactual (10% increase in consumption)

bc = bc * 1.1;
interm(o,'hh') = interm(o,'hh') * 1.1;
$include minimal.gen
solve minimal using mcp;

* Results

parameters
  res_com           results by commodity in % change from basis
  res_agg           aggregate results in % change from basis; 

res_com('output',o) = (y.l(o) - 1) * 100;
res_com('cons',o)$interm(o,'hh') = (cons.l(o)/interm(o,'hh') - 1) * 100;
res_com('import',o) = (m.l(o) - 1) * 100;
res_com('export',o) = (e.l(o) - 1) * 100;
res_com('price',o) = (pd.l(o) - 1) * 100;

res_agg('employ') = - upl.l * 100;
res_agg('ra_inc') = (ra.l/expend - 1 ) * 100;

option decimals = 6;
display res_com, res_agg;
